﻿using System.Web.Mvc;
using AutoMapper;
using ITTestingSystem.BusinessLogic.DataServices.Abstract;
using ITTestingSystem.BusinessLogic.Enums;
using ITTestingSystem.BusinessLogic.PasswordHasher;
using ITTestingSystem.Domain.Entities;
using ITTestingSystem.Extentions.Modules.AuthenticationProvider;
using ITTestingSystem.Extentions.Modules.EmailService;
using ITTestingSystem.Models.Account;

namespace ITTestingSystem.Controllers
{
    public partial class AccountController : Controller
    {
        private readonly IUserService _userService;
        private readonly IAuthenticationProvider _authenticationProvider;
        private readonly IMailService _emailService;
        private readonly IPasswordHasher _passwordHasher;

        public AccountController
            (
                IAuthenticationProvider authenticationProvider,
                IUserService userService,
                IMailService emailService,
                IPasswordHasher passwordHasher
            )
        {
            _authenticationProvider = authenticationProvider;
            _userService = userService;
            _emailService = emailService;
            _passwordHasher = passwordHasher;
        }

        public virtual ActionResult AccessLimited()
        {
            return View();
        }

        [HttpGet]
        public virtual ActionResult LogOn()
        {
            var logOnView = new LogOnViewModel();

            return View(logOnView);
        }

        [HttpPost]
        public virtual ActionResult LogOn(LogOnViewModel logOnViewModel)
        {
            if (ModelState.IsValid == false)
            {
                return View(logOnViewModel);
            }

            var authenticationResult = _authenticationProvider.Authenticate
                            (
                                logOnViewModel.Login,
                                _passwordHasher.GetPasswordHash(logOnViewModel.Password),
                                logOnViewModel.RememberMe
                            );

            switch (authenticationResult)
            {
                case AuthenticationResult.Authenticated:
                    {
                        return RedirectToAction("Index", "Home");
                    }

                case AuthenticationResult.EmailNotConfirmed:
                    {
                        ModelState.AddModelError(string.Empty, "Реєстрацію ще не підтверджено");
                        break;
                    }

                default:
                    {
                        ModelState.AddModelError(string.Empty, "Користувач з такими даними відсутній");
                        break;
                    }
            }

            return View(logOnViewModel);
        }


        public virtual ActionResult LogOff()
        {
            _authenticationProvider.SignOut();

            return RedirectToAction("LogOn");
        }

        [HttpGet]
        public virtual ActionResult Register()
        {
            var registerViewModel = new RegisterViewModel();

            return View(registerViewModel);
        }

        [HttpPost]
        public virtual ActionResult Register(RegisterViewModel registerViewModel)
        {
            if (ModelState.IsValid == false)
            {
                return View(registerViewModel);
            }

            if (_userService.UserExist(registerViewModel.Email, registerViewModel.Login))
            {
                ModelState.AddModelError(string.Empty, "Користувач з такими даними вже існує");

                return View(registerViewModel);
            }

            registerViewModel.Password = _passwordHasher.GetPasswordHash(registerViewModel.Password);

            var user = Mapper.Map<User>(registerViewModel);

            _userService.Add(user);

            // Унікальний ідентифікатор для url при підтвердженні реєстрації

            var token = _userService.GetUserToken(user);

            _emailService.ConfirmRegistration(registerViewModel.Email, token);

            return View("RegisterSuccess");
        }

        public virtual ActionResult RegisterConfirmed(string token)
        {
            token = Server.UrlDecode(token);

            var result = _userService.SetPasswordConfirm(token);

            if (result)
            {
                return View();
            }

            return new HttpNotFoundResult();
        }

        [ChildActionOnly]
        public virtual ActionResult LoginWidget()
        {
            if (System.Web.HttpContext.Current.Request.IsAuthenticated)
            {
                ViewBag.Action = MVC.Account.LogOff();
                ViewBag.LinkText = "Вихід";
            }
            else
            {
                ViewBag.Action = MVC.Account.LogOn();
                ViewBag.LinkText = "Вхід";
            }

            return PartialView("_LoginWidget");
        }
    }
}
